#include "stdafx.h"
#include "main_generator.h"

bool call_detected_while(detected_callback detected_function, CFG *cfg, char **src, BasicBlock *parent_block, int str_index) {
	result res;

	unnext(src, str_index);
	if(detected_function(cfg, &res, src) == false) {
		return false;
	}

	attach_basic_block(cfg, parent_block, res.start);
	attach_basic_block_multi_parent(cfg, res.ends, parent_block);

	return true;
}

bool detected_while(CFG *cfg, result *r, char **src) {
	BasicBlock *condition_block;
	char c, *source, buffer[1024] = { 0, }, str[1024] = { 0, };
	int str_index = 0;

	while(next(src) != '(');
	source = *src;
	while(next(src) != ')');
	*((*src)-1) = 0;
	
	trim(buffer, source);

	r->start = condition_block = make_basic_block(ct_while, buffer);

	r->ends = create_list();
	while((c = next(src)) != 0) {
		str[str_index++] = c;
		trim(buffer, str);

		if(c == '{') {
			CFG *new_cfg = make_cfg();
			if(parsing(new_cfg, src) != none)
				return false;

			attach_basic_block_multi_child(cfg, condition_block, new_cfg->start->connect_bb_list);
			attach_basic_block_multi_parent(cfg, new_cfg->end->parent_list, condition_block);

			detach_body(new_cfg);

			free(new_cfg);
			memset(str, 0, 1024);
			str_index = 0;

			break;
		} else if(c == ';') {
			if(!strncmp(buffer, "if", strlen("if"))) {
				if(call_detected_while(detected_if, cfg, src, condition_block, str_index) == false) {
					return false;
				}
			} else if(!strncmp(buffer, "for", strlen("if"))) {
				if(call_detected_while(detected_for, cfg, src, condition_block, str_index) == false) {
					return false;
				}
			} else if(!strncmp(buffer, "while", strlen("while"))) {
				if(call_detected_while(detected_while, cfg, src, condition_block, str_index) == false) {
					return false;
				}
			} else if(!strncmp(buffer, "switch", strlen("switch"))) {
				if(call_detected_while(detected_switch, cfg, src, condition_block, str_index) == false) {
					return false;
				}
			} else {
				BasicBlock *bb;
				trim(buffer, str);

				bb = make_basic_block(ct_statement, buffer);
				attach_basic_block(cfg, bb, condition_block);
				attach_basic_block(cfg, condition_block, bb);
			}

			memset(str, 0, 1024);
			str_index = 0;
			break;
		}
	}

	// unnext(src, str_index);

	add_list(r->ends, condition_block);
	
	return true;
}